/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package lbim.protocol;


import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import javax.microedition.io.Connector;
import javax.microedition.io.StreamConnection;


/**
 *
 * @author Jestan
 */
public class CirChannelHandler implements Runnable{
    private LbImProtocol protocol;
    private String ip = "127.0.0.1";
    private String port = "8081";

    private OutputStream dos;
    private InputStreamReader streamReader;
    private StreamConnection socketConnection;


    public static String PING = "PING\r\n";
    public static String OK = "OK";
    public static String NM = "NM";;

    private String hello;

    public static final int START = 1;
    public static final int RUNNING = 2;
    public static final int WAITING = 4;
    public static final int STOP = 3;
    private volatile  int state = -1;



    public CirChannelHandler(LbImProtocol protocol, String userName, String sid) {
        this.protocol = protocol;
        this.hello = userName+":"+sid+"\r\n";

        Thread t = new Thread(this);
        t.start();

    }

    private void closeImpl() {
        try {
            sendCloseMessage();
            socketConnection.close();
            System.out.println("[CirChannelHandler]  shutdown the channel and closing stream");
        } catch (IOException ex) {
        }
        System.out.println("[CirChannelHandler]  channelhandler thread is stopped");
    }


    private void setupChannel() {
        try {
            String name = "socket://" + ip + ":" + port;
            socketConnection = (StreamConnection) Connector.open(name, Connector.READ_WRITE);
            dos = socketConnection.openDataOutputStream();
            streamReader = new InputStreamReader(socketConnection.openInputStream());
            state = RUNNING;
        } catch (IOException ex) {
            ex.printStackTrace();
            state = START;
        }
    }

    private void sleep() {
        try {
            Thread.sleep(8000);
        } catch (InterruptedException e) {
//            do nothing
        }
    }
    private void sendHello() {
        try {
            dos.write(hello.getBytes());
            dos.flush();
            String message = readInputStream();
            System.out.println("[CirChannelHandler] CIR message received :"+message);
            state = RUNNING;
        } catch (IOException e) {
            state = START;
        }
    }

    private void sendKeepAlive() {
        try {
            dos.write(PING.getBytes());
            dos.flush();
            String message = readInputStream();
            System.out.println("[CirChannelHandler] CIR message received :"+message);
            state = RUNNING;
        } catch (IOException e) {
            state = START;
        }
    }
    private String readInputStream() throws IOException {
        String output = "";
        int inputChar;
        int bs;
        while ((inputChar = streamReader.read()) != 13) {
            if (inputChar == -1) {
                break;
            }
            output += (char) inputChar;
        }
        output = output.trim();
        if(output.equals(NM)) {
            protocol.sendPoolingMessage();
             System.out.println("[CirChannelHandler]  NM ack received from server, so sending a pooling msg");
        }
        return output;
    }
    public void run() {
        state = START;
        while (state != STOP) {
            if (state == START) {
                setupChannel();
                sendHello();
                continue;
            } else if (state == RUNNING) {
                sendKeepAlive();
                sleep();
            }

        }
        closeImpl();

    }

    private void sendCloseMessage() {
        try {
            System.out.println("[CirChannelHandler] sending close message");
            dos.write("CLOSE\r\n".getBytes());
            dos.flush();
            String message = readInputStream();
            System.out.println("[CirChannelHandler] close ack received :" + message);
        } catch (IOException e) {
        }
    }

    public void shutdown() {
        state = STOP;
    }

}
